package com.sky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sky.constant.RedisConstant;
import com.sky.constant.RubbishSetConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Category;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.SetmealDish;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.result.PageResult;
import com.sky.service.IDishFlavorService;
import com.sky.service.IDishService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.vo.DishVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.sql.Array;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜品 服务实现类
 * </p>
 *
 * @author chensheng
 * @since 2025-08-08
 */
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements IDishService {
    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorMapper dishFlavorMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private IDishFlavorService dishFlavorService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 新增菜品和对应的口味数据
     *
     * @param dishDTO
     */
    @Transactional
    @Override
    public void saveWithFlavor(DishDTO dishDTO) {
        // 保存菜品数据
//        dishDTO.getFlavors().forEach(flavor -> flavor.setDishId(dishDTO.getId()));
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
    /*    dish.setCategoryId(dishDTO.getCategoryId());
        dish.setDescription(dishDTO.getDescription());
        dish.setImage(dishDTO.getImage());
        dish.setName(dishDTO.getName());
        dish.setPrice(dishDTO.getPrice());*/
        dish.setStatus(StatusConstant.ENABLE);
        dishMapper.insert(dish);
        //保存口味数据
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (flavors != null && flavors.size() > 0) {
            flavors.forEach(flavor -> flavor.setDishId(dish.getId()));
            dishFlavorMapper.insert(flavors);
        }
        //3.移除垃圾图片
        RubbishSetConstant.RUBBISH_SET.remove(dishDTO.getImage());

        //新增菜品对应的分类id对应的缓存删除
        redisTemplate.delete(RedisConstant.CATEGORY_KRY + dish.getCategoryId());
    }

    /**
     * 根据分类id查询菜品
     *
     * @param categoryId
     * @return
     */
    @Override
    public List<DishVO> getDishById(Long categoryId) {

        return dishMapper.selectByCategoryId(categoryId);
    }

    @Override
    public void editDish(DishDTO dishDTO) {
        //1.修改菜品数据
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        dishMapper.updateById(dish);
        //2.修改口味数据
        dishFlavorMapper.delete(new LambdaQueryWrapper<DishFlavor>().eq(DishFlavor::getDishId, dishDTO.getId()));
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (!CollectionUtils.isEmpty(flavors)) {
            flavors.forEach(dishFlavor -> dishFlavor.setDishId(dishDTO.getId()));
            dishFlavorMapper.insert(flavors);
        }
        //清理缓存，新老菜品对应的分类id的缓存都要删除
        // 先获取修改前的菜品信息
        Dish oldDish = dishMapper.selectById(dishDTO.getId());
        Set<Long> categoryIds = new HashSet<>();
        // 添加修改前的分类ID
        if (oldDish != null) {
            categoryIds.add(oldDish.getCategoryId());
        }
        // 添加修改后的分类ID
        categoryIds.add(dish.getCategoryId());
        
        // 清理所有相关分类的缓存
        categoryIds.forEach(categoryId -> 
            redisTemplate.delete(RedisConstant.CATEGORY_KRY + categoryId));
    }

    /**
     * 根据id查询菜品和对应的口味数据
     */
    @Override
    public DishVO findById(Long id) {
        //1.查询菜品数据
        Dish dish = dishMapper.selectById(id);

        //2.查询口味数据
        List<DishFlavor> flavors = dishFlavorMapper.selectList(new LambdaQueryWrapper<DishFlavor>().eq(DishFlavor::getDishId, id));

        //3.封装数据并返回
        DishVO dishVO = new DishVO();
        BeanUtils.copyProperties(dish, dishVO);
        dishVO.setFlavors(flavors);
        return dishVO;

    }

    /**
     * 批量删除菜品
     */
    @Transactional
    @Override
    public void deleteByIds(List<Long> ids) {
        //0.根据ids查询菜品数据
        List<Dish> dishs = dishMapper.selectByIds(ids);
        //1.售卖的不能删除
        for (Dish dish : dishs) {
            if (dish.getStatus().equals(StatusConstant.ENABLE)) {
                //起售中的菜品不能删除
                throw new DeletionNotAllowedException("起售中的菜品不能删除");
            }
        }
        //2.被套餐关联的不能删除
        LambdaQueryWrapper<SetmealDish> qw = new LambdaQueryWrapper<>();
        qw.in(SetmealDish::getDishId, ids);
        Long count = setmealDishMapper.selectCount(qw);
        if (count > 0) {
            //有套餐关联的菜品不能删除
            throw new DeletionNotAllowedException("有套餐关联的菜品不能删除");
        }

        //3.删除菜品的时候，需要同时删除口味数据
        dishFlavorMapper.delete(new LambdaQueryWrapper<DishFlavor>().in(DishFlavor::getDishId, ids));
        dishMapper.deleteByIds(ids);
        //4.删除垃圾图片
        for (Dish dish : dishs) {
            String image = dish.getImage();
            if (StringUtils.hasText(image)) {
                //删除图片
                //TODO
            }

        }
        //封装菜品对应分离的缓存
        Set<String> collect = dishs.stream().map(new Function<Dish, String>() {
         @Override
         public String apply(Dish dish) {
         return RedisConstant.CATEGORY_KRY + dish.getCategoryId();
         }
}
        ).collect(Collectors.toSet());
        //清理缓存
        redisTemplate.delete(collect);

    }

    /**
     * 分页查询
     */
    @Override
    public PageResult pageQuery(DishPageQueryDTO dDTO) {

        Page<DishVO> page = Page.of(dDTO.getPage(), dDTO.getPageSize());

        dishMapper.selectByCondition(page, dDTO);
       /* LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        qw.like(dDTO.getName()!=null,Dish::getName,dDTO.getName())
                .eq(dDTO.getCategoryId()!=null,Dish::getCategoryId,dDTO.getCategoryId())
                .eq(dDTO.getStatus()!=null,Dish::getStatus,dDTO.getStatus())
                .orderByDesc(Dish::getUpdateTime);
        dishMapper.selectPage(page, qw);*/
        return PageResult.builder()
                .total(page.getTotal())
                .records(page.getRecords())
                .build();


    }

    @Override
    public List<DishVO> listWithFlavor(Dish dish) {
        //1.查询redis数据
        List<DishVO> dishVOList = (List<DishVO>) redisTemplate.opsForValue().get(RedisConstant.CATEGORY_KRY + dish.getCategoryId());
        if (dishVOList != null) {
            return dishVOList;
        }

/*        List<Dish> dishes = dishMapper.selectList(new LambdaQueryWrapper<Dish>()
                .eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId())
                .eq(dish.getStatus() != null, Dish::getStatus, dish.getStatus())
                .orderByDesc(Dish::getUpdateTime));
        if (CollectionUtils.isEmpty(dishes)){
            return Collections.emptyList();
        }
        List<DishVO> dishVOList = dishes.stream().map(temp ->{
                DishVO dishVO = new DishVO();
                BeanUtils.copyProperties(dish, dishVO);
                //补全菜品的口味数据
            List<DishFlavor> dishFlavors = dishFlavorMapper.selectList(new LambdaQueryWrapper<DishFlavor>().eq(DishFlavor::getDishId, dish.getId()));
            dishVO.setFlavors(dishFlavors);
            return dishVO;
    }).collect(Collectors.toList());*/
        List<Dish> dishList = dishMapper.list(dish);
        dishVOList = new ArrayList<>();
        for (Dish d : dishList) {
            DishVO dishVO = new DishVO();
            BeanUtils.copyProperties(d, dishVO);
            //根据菜品id擦好像对应的口味
            List<DishFlavor> flavors = dishFlavorMapper.getByDishId(d.getId());
            dishVO.setFlavors(flavors);
            dishVOList.add(dishVO);
        }
        //2.数据存入redis
        redisTemplate.opsForValue().set(RedisConstant.CATEGORY_KRY + dish.getCategoryId(), dishVOList);
        return dishVOList;
    }
}
